package com.zx.sercurity;

import android.content.Context;
import android.content.pm.PackageManager;

import com.zx.sercurity.util.BootloaderUtils;
import com.zx.sercurity.util.DeviceUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

public class RootRisk implements RiskControlInterface<RiskResult.RootRiskResult> {

    @Override
    public RiskResult.RootRiskResult riskCheck(Context context) {
        ArrayList<String> result = new ArrayList<>();
        result.addAll(checkRootFile());
        result.addAll(checkSUCommend());
        result.addAll(checkBuildTags());
        result.addAll(checkSystemProp());
        result.addAll(isXposedPresent());
        result.addAll(checkUnlockBootloader());
        if (result.isEmpty()) {
            return new RiskResult.RootRiskResult(false, result);
        } else {
            return new RiskResult.RootRiskResult(true, result);
        }
    }

    public List<String> checkUnlockBootloader() {
        if (BootloaderUtils.isBootloaderUnlocked()) {
            return Collections.singletonList("检查到解锁Bootloader");
        } else {
            return Collections.emptyList();
        }
    }

    /**
     * 检查常用root文件
     *
     * @return
     */
    public List<String> checkRootFile() {
        ArrayList<String> result = new ArrayList<>();
        String[] paths = {
                "/system/bin/su",
                "/system/xbin/su",
                "/sbin/su",
                "/system/su",
                "/system/bin/.ext/.su",
                "/system/usr/we-need-root/su",
                "/data/local/xbin/su",
                "/data/local/bin/su",
                "/data/local/su"
        };
        for (String path : paths) {
            if (new File(path).exists()) {
                result.add("检查到root相关文件/文件夹：" + path);
            }
        }
        return result;
    }

    /**
     * 检查su命令
     *
     * @return
     */
    public List<String> checkSUCommend() {
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("su");
            return Collections.singletonList("检查到可执行超级管理员命令");
        } catch (IOException e) {
            return Collections.emptyList();
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
    }

    /**
     * 检查Build.TAGS
     *
     * @return
     */
    public List<String> checkBuildTags() {
        String buildTags = android.os.Build.TAGS;
        if (buildTags != null && buildTags.contains("test-keys")) {
            return Collections.singletonList("检查到 Build.TAGS");
        } else {
            return Collections.emptyList();
        }
    }

    /**
     * 检查是否存在 Xposed 框架
     */
    public List<String> isXposedPresent() {
        try {
            Class.forName("de.robv.android.xposed.XposedHelpers");
            return Collections.singletonList("检查到Xposed框架");
        } catch (Throwable e) {
            return Collections.emptyList();
        }
    }


    /**
     * 检查系统属性
     *
     * @return
     */
    public List<String> checkSystemProp() {
        //三星设备无视宽容政策
        ArrayList<String> result = new ArrayList<>();
        String[] props;
        if (DeviceUtils.getDeviceBrand().equalsIgnoreCase("Samsung")) {
            props = new String[]{
                    "ro.debuggable"
            };
        } else {
            props = new String[]{
                    "ro.build.selinux",
                    "ro.debuggable"
            };
        }
        for (String prop : props) {
            try {
                Process process = Runtime.getRuntime().exec("getprop " + prop);
                BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line = reader.readLine();
                if (line != null && (line.contains("1") || line.contains("permissive"))) {
                    result.add("检查到系统环境属性异常:" + prop);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }


}
